Skip to content

Update HintsEditor layout and collapse behavior#5942

Open
Abhishek-Punhani wants to merge 2 commits into
learningequality:unstablefrom
Abhishek-Punhani:Issue5914
Open

Update HintsEditor layout and collapse behavior#5942
Abhishek-Punhani wants to merge 2 commits into
learningequality:unstablefrom
Abhishek-Punhani:Issue5914

Conversation

@Abhishek-Punhani
Copy link
Copy Markdown
Member

@Abhishek-Punhani Abhishek-Punhani commented May 27, 2026

Updated HintsEditor layout according to new figma specs and added collapse behavior

Summary

Changes:

  • Added Collapsible header with new heading content "Hints (optional)"
  • Each hint is now rendered as plain input in view mode and toggles to TipTapEditor in edit mode.
  • The current "New hint" button is replaced with a dashed-border + Add hint button, centered and full-width.
image

References

fixes #5914

Reviewer guidance

  1. Open a channel in the Studio channel editor.
  2. Select or create an Exercise node.
  3. In the edit panel, navigate to the Questions tab.
  4. Open a question — the Hints section appears at the bottom of the question card, collapsed by default.

AI usage

Used Antigravity for final review and nitpicks.

…apse behavior

Signed-off-by: Abhishek-Punhani <punhani.manavabhi@gmail.com>
@learning-equality-bot
Copy link
Copy Markdown

👋 Hi @Abhishek-Punhani, thanks for contributing!

For the review process to begin, please verify that the following is satisfied:

  • Contribution is aligned with our contributing guidelines

  • Pull request description has correctly filled AI usage section & follows our AI guidance:

    AI guidance

    State explicitly whether you didn't use or used AI & how.

    If you used it, ensure that the PR is aligned with Using AI as well as our DEEP framework. DEEP asks you:

    • Disclose — Be open about when you've used AI for support.
    • Engage critically — Question what is generated. Review code for correctness and unnecessary complexity.
    • Edit — Review and refine AI output. Remove unnecessary code and verify it still works after your edits.
    • Process sharing — Explain how you used the AI so others can learn.

    Examples of good disclosures:

    "I used Claude Code to implement the component, prompting it to follow the pattern in ComponentX. I reviewed the generated code, removed unnecessary error handling, and verified the tests pass."

    "I brainstormed the approach with Gemini, then had it write failing tests for the feature. After reviewing the tests, I used Claude Code to generate the implementation. I refactored the output to reduce verbosity and ran the full test suite."

Also check that issue requirements are satisfied & you ran pre-commit locally.

Pull requests that don't follow the guidelines will be closed.

Reviewer assignment can take up to 2 weeks.

@Abhishek-Punhani
Copy link
Copy Markdown
Member Author

@AlexVelezLl , Could you guide me how can I change the icon color in KButton ? in Add hint
Also the figma spec doesnt have assessmentToolBar?

@AlexVelezLl
Copy link
Copy Markdown
Member

Could you guide me how can I change the icon color in KButton ?

Hey @Abhishek-Punhani! For this, you can use the KButton icon slot instead and set the color to KIcon directly :). You can also use the default slot to place both the button label and the icon if you want more control over the layout.

Also the figma spec doesnt have assessmentToolBar?

Yeah, it seems this was an oversight in the designs, but we should keep the assessment toolbar for hints too, so that we can reorder and remove hints.

@Abhishek-Punhani
Copy link
Copy Markdown
Member Author

Hey @Abhishek-Punhani! For this, you can use the KButton icon slot instead and set the color to KIcon directly :). You can also use the default slot to place both the button label and the icon if you want more control over the layout.

@AlexVelezLl, I tried using the KIcon and apply color, color was applied but they are not aligning properly

@AlexVelezLl
Copy link
Copy Markdown
Member

AlexVelezLl commented May 27, 2026

Yeah, I imagine. We can go with the default slot, then, and see how it goes. Also, many times we need to reset the KIcon relative position like this with this class being applied to this component, because KIcon has a harcoded relative position that sometimes mess up with some layouts. Perhaps this can help?

…yling

Signed-off-by: Abhishek-Punhani <punhani.manavabhi@gmail.com>
@AlexVelezLl AlexVelezLl requested a review from rtibblesbot May 27, 2026 13:35
@learning-equality-bot
Copy link
Copy Markdown

📢✨ Before we assign a reviewer, we'll turn on @rtibblesbot to pre-review. Its comments are generated by an LLM, and should be evaluated accordingly.

Copy link
Copy Markdown
Contributor

@rtibblesbot rtibblesbot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid implementation of the collapsible hints section with clean view/edit mode switching. CI passing.

  • blocking: hintViewTextStyle is referenced in the desktop layout but never defined — see inline comment
  • suggestion: View mode renders raw Markdown string — may be a regression for formatted hints
  • suggestion: Collapsible header div is not keyboard-accessible
  • praise: openHintsSection test helper makes the new collapse behaviour self-documenting

@rtibblesbot's comments are generated by an LLM, and should be evaluated accordingly

How was this generated?

Reviewed the pull request diff checking for:

  • Correctness: bugs, edge cases, undocumented behavior, resource leaks, hardcoded values
  • Design: unnecessary complexity, naming, readability, comment accuracy, redundant state
  • Architecture: duplicated concerns, minimal interfaces, composition over inheritance
  • Testing: behavior-based assertions, mocks only at hard boundaries, accurate coverage
  • Completeness: missing dependencies, unupdated usages, i18n, accessibility, security
  • Principles: DRY (same reason to change), SRP, Rule of Three (no premature abstraction)
  • Checked CI status and linked issue acceptance criteria
  • For UI changes: inspected screenshots for layout, visual completeness, and consistency

<div
v-if="!isHintOpen(hintIdx)"
class="hint-view-text"
:style="hintViewTextStyle"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocking: :style="hintViewTextStyle" is bound here but hintViewTextStyle is never defined in computed (only hintPlaceholderStyle and buttonAppearanceOverrides are defined). Vue will warn and no style will be applied. The equivalent div in the touch layout (line 64) has no style binding, so it's unclear what style was intended. Either define the computed property or remove the binding.

:style="hintViewTextStyle"
>
<span :style="isHintEmpty(hint) ? hintPlaceholderStyle : {}">
{{ hintDisplayText(hint, hintIdx) }}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: hint.hint is stored as Markdown (TipTapEditor emits via getMarkdown()). Rendering it with {{ }} will show raw Markdown symbols — e.g. a hint containing **bold** will display with the asterisks visible. The previous code used TipTapEditor in view mode which rendered Markdown properly.

If the intent is to show a simplified plain-text preview (matching the design spec's input-like appearance), that's fine — but worth confirming that any existing hints with formatting are acceptable to display as raw Markdown.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we should render the formatted markdown.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, thanks for confirming.

{{ $tr('noHintsPlaceholder') }}
<div
class="hints-header"
@click="sectionOpen = !sectionOpen"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: The collapsible trigger is a plain div with only a click handler. Keyboard users who navigate with Tab can't focus or activate it. Consider adding tabindex="0", role="button", and a keydown handler (@keydown.enter and @keydown.space) to toggle sectionOpen, or replacing the div with a <button> element.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think replacing the div with a button may be the best path forward. Given that this follows the accessible pattern of an accordion, we can follow the same pattern as the StudioAccordion component (i.e., the trigger being a button element, with an aria-controls, aria-expanded, etc).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great approach — following the StudioAccordion pattern (button element with aria-controls, aria-expanded, etc.) is exactly the right model for an accordion trigger. Thanks for pointing to that reference.

};

const openHintsSection = async user => {
await user.click(screen.getByText(HintsEditor.$trs.hintsLabel));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Extracting openHintsSection as a named helper is a nice touch — it makes the new UX requirement (section must be opened before interacting with its contents) explicit and self-documenting across all tests.

Copy link
Copy Markdown
Member

@AlexVelezLl AlexVelezLl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some comments to match the specs!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add some tests for the toggle flow of the show hints button?

<VCard
flat
:class="hintClasses(hintIdx)"
<VDivider class="full-width-divider" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use a plain div with a $themeTokens.fineLine color instead?

<div>
<div
v-if="!hints || !hints.length"
class="card-border-light pa-3"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we are pretty much rewriting this component, could we get rid of the Vuetify things, please? e.g., this car-border-light uses some Vuetify colors, and this pa-3 is a Vuetify class. It would be great if we could start getting rid of some of these.

data-test="hint"
@click="onHintClick($event, hintIdx)"
>
<VCard
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we achieve this with a plain div, too? Also, could we use the fineLine border color to match the figma specs?

<!-- Touch device & desktop layout with toolbar above -->
<template v-if="isTouchDevice || screenSizeLevel <= 3">
<VLayout class="mb-2">
<VSpacer />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can achieve this layout without Vuetify, that'd be great!

Comment on lines +66 to +68
<span :style="isHintEmpty(hint) ? hintPlaceholderStyle : {}">
{{ hintDisplayText(hint, hintIdx) }}
</span>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the placeholder, we should use the color http://design-system.learningequality.org/colors/#palette-grey-v_300

{{ $tr('noHintsPlaceholder') }}
</div>
<div
v-for="(hint, hintIdx) in hints"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this isn't on the Figma specs, but can we add some gap between hints, similar to the gap that the answers list has?

Image

.hint-editor-button {
justify-content: center;
width: 100%;
margin-top: 10px;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The button on the specs has 11px vertical padding. Could we override the line-height: unset and padding: 11px 16px here to match that? and also a border-radius of 4px

Comment on lines +149 to +155
<template #icon>
<KIcon
icon="plus"
:color="$themePalette.grey.v_700"
class="add-hint-icon"
/>
</template>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the KButton icon container is also adding some relative top value 🫠. Could we use just the default slot of the KButton to render the button label and center the icon with a flex container? And also would be great to add some gap (10px) between the icon and the label.

<KButton
:text="$tr('newHintBtnLabel')"
class="hint-editor-button"
:style="{ border: `1px dashed ${$themePalette.grey.v_400}` }"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, the border color should be $themeTokens.fineLine. Also, could we define this border style on the buttonAppearanceOverrides property too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update HintsEditor layout and collapse behavior

3 participants